home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Apple Developer Connection Student Program
/
ADC Tools Sampler CD Disk 3 1999.iso
/
Cool Demos, SDKs, & Tools
/
Demos⁄Tools⁄Offers
/
Alpha ƒ
/
Tcl
/
Menus
/
wwwMenu.tcl
< prev
Wrap
Text File
|
1999-03-18
|
25KB
|
1,005 lines
## -*-Tcl-*- (install)
# ###################################################################
# Vince's Additions - an extension package for Alpha
#
# FILE: "wwwMenu.tcl"
# created: 30/4/97 {11:04:46 am}
# last update: 18/3/1999 {4:57:05 pm}
# Author: Vince Darley
# E-mail: <darley@fas.harvard.edu>
# mail: Division of Applied Sciences, Harvard University
# Oxford Street, Cambridge MA 02138, USA
# www: <http://www.fas.harvard.edu/~darley/>
#
# Copyright (c) 1997-1998 Vince Darley, all rights reserved
#
# A simple text-only WWW browser. Since Alpha can't use the http
# protocol, it can only browse files locally, but could be easily
# extended if/when Alpha upgrades to Tcl8.0
#
# Basic features: handles most common html tags, and has a
# history list and a back/forward capability. Can handle mailto,
# ftp and java applets itself; all other stuff is optionally
# shipped off to Internet Config.
#
# Use the cursor keys, mouse or cmd-[] to move from web page
# to web page as follows:
#
# <- or cmd-[ goto previous page
# cmd-] goto next page
# -> or return goto current link
# up/down arrow highlight previous/next link
# mouse-click goto clicked-upon link
#
# You can also select 'view source' from the menu. Many keys
# are also bound to imitate the browser 'lynx'.
#
# Advanced features:
#
# ctrl-return allows you to edit the original of the link currently
# selected.
#
# Using the WWW mode preferences you can ask Alpha to handle
# some URL types internally (currently mailto: and ftp: only).
# Also Java applets may be sent to your javaviewer application
# (for example the 'Apple Applet Runner' which is free from apple).
#
# To Do:
#
# Could be faster (i.e. it's probably useless on 680x0 machines),
# and it would be nice if Alpha added Tcl's socket capability.
# However it's reasonably useful for browsing local HTML
# documentation.
#
# Installation: (requires Alpha 7.0b1)
#
# It's most useful if you either make the wwwMenu a
# global menu (Config->Global->PackageMenus...), or if you attach a
# key binding in your prefs.tcl to view a file; something like
# this:
# # Bind cmd-F12 to parse a file
# Bind 0x6f <c> wwwParseFile
#
# This file is copyright Vince Darley 1997, but freely distributable
# provided you note any modifications you make below. Please send
# me bug fixes and improvements.
# ###################################################################
##
alpha::menu wwwMenu 1.2 "global WWW HTML" "•286" {
addMode WWW wwwMenu {*.www} wwwMenu
ensureset javaviewerSig "WARZ"
set {newDocTypes(New Web Browser)} wwwParseFile
} {wwwMenu} {} maintainer {
"Vince Darley" darley@fas.harvard.edu <http://www.fas.harvard.edu/~darley/>
} uninstall {this-file} help {
Browse local html pages inside Alpha
}
newPref v header1Color blue WWW
newPref v header2Color red WWW
newPref v header3Color red WWW
newPref v linkColor green WWW
newPref v visitedLinkColor cyan WWW
newPref f mailtoLinksInternal 0 WWW
newPref f ftpLinksInternal 0 WWW
newPref f runJavaAppletsDirectly 0 WWW
newPref f wwwSendRemoteLinks 0 WWW
# To perform a special action with a new URL type, add an array
# entry indicating the procedure to be called with the remainder
# of the URL. You must also add a global variable or modeVar
# as above so that the user can choose whether Alpha should handle
# that type via the given procedure. If any of this fails, the
# URL is just given to Internet Config to deal with. Note that
# 'file' URL's are always handled internally.
set wwwUrlAction(mailto) "mailNewMsg"
set wwwUrlAction(ftp) "ftpWWWLink"
set wwwUrlAction(file) "fileWWWLink"
set wwwUrlAction(java) "javaWWWLink"
set _wwwAlwaysInternal [list file java]
proc wwwMenu {} {}
Menu -n $wwwMenu -p wwwMenuProc -M WWW {
"/S<U<OswitchToBrowser"
"(-"
"viewHtmlFile…"
"viewThisFile"
"viewSource"
"/a<S<EselectLink"
"/a<S<BmodifyLink"
"/\[back"
"/\]forward"
"reload"
{Menu -m -n gotoPage -p wwwMenuProc {
}}
"forgetHistory"
}
# Bind various keys to imitate lynx.
##
# +++ Keystroke Commands +++
#
# MOVEMENT: Down arrow - Highlight next topic
# Up arrow - Highlight previous topic
# Right arrow, - Jump to highlighted topic
# Return, Enter
# Left arrow - Return to previous topic
#
# SCROLLING: + - Scroll down to next page (Page-Down)
# - - Scroll up to previous page (Page-Up)
# SPACE - Scroll down to next page (Page-Down)
# b - Scroll up to previous page (Page-Up)
# CTRL-A - Go to first page of the current document (Home)
# CTRL-E - Go to last page of the current document (End)
# CTRL-B - Scroll up to previous page (Page-Up)
# CTRL-F - Scroll down to next page (Page-Down)
# CTRL-N - Go forward two lines in the current document
# CTRL-P - Go back two lines in the current document
# ) - Go forward half a page in the current document
# ( - Go back half a page in the current document
##
Bind 0x7d wwwDown WWW
Bind 0x7e wwwUp WWW
Bind 0x7c wwwSelectLink WWW
Bind 0x24 wwwSelectLink WWW
Bind 0x34 wwwSelectLink WWW
Bind 0x7b wwwBack WWW
Bind 0x24 <z> wwwModifyLink WWW
Bind 0x24 <o> wwwEditLinkedDocument WWW
Bind 0x79 "wwwKey pageForward" WWW
Bind 0x74 "wwwKey pageBack" WWW
Bind 0x31 "wwwKey pageForward" WWW
Bind '+' "wwwKey pageForward" WWW
Bind '-' "wwwKey pageBack" WWW
Bind 'b' "wwwKey pageForward" WWW
Bind 0x7e <c> "wwwKey Home" WWW
Bind 0x7d <c> "wwwKey End" WWW
Bind 'a' <z> "wwwKey Home" WWW
Bind 'e' <z> "wwwKey End" WWW
Bind 'b' <z> "wwwKey pageBack" WWW
Bind 'f' <z> "wwwKey pageForward" WWW
Bind 'n' <z> "wwwKey twoLinesForward" WWW
Bind 'p' <z> "wwwKey twoLinesBack" WWW
Bind ')' "wwwKey halfPageForward" WWW
Bind '(' "wwwKey halfPageBack" WWW
Bind 'e' "wwwMenuProc x viewSource" WWW
Bind 'g' wwwParseFile WWW
Bind 'c' wwwCopyLinkLocation WWW
Bind '\t' wwwDown WWW
Bind 'r' wwwReload WWW
set wwwSendRemoteLinks 0
set _wwwHistory ""
set _wwwHpos -1
set _wwwVisited ""
set _wwwPre 0
##
# -------------------------------------------------------------------------
#
# "wwwKey" --
#
# Handle page-movement key bindings.
# -------------------------------------------------------------------------
##
proc wwwKey {key} {
if {[set a [_wwwKeyPosition $key]] != ""} {
_wwwHighlightLink [lindex [wwwGetCurrentLink] $a]
}
}
proc _wwwKeyPosition {key} {
switch $key {
"Home" {
goto [minPos]
wwwHighlightLink 0
return ""
}
"End" {
goto [maxPos]
wwwHighlightLink -1
return ""
}
"pageBack" {
pageBack
return 0
}
"pageForward" {
pageForward
return 1
}
default {
set p [getPos]
switch $key {
"twoLinesForward" {
scrollDownLine
scrollDownLine
return [_wwwEnsureOn $p]
}
"twoLinesBack" {
scrollUpLine
scrollUpLine
return [_wwwEnsureOn $p]
}
"halfPageForward" {
getWinInfo a
set lines $a(linesdisp)
set top $a(currline)
set q [rowColToPos [expr $top + ${lines}/2] 0]
goto [rowColToPos [expr $top + $lines + ($lines /2) -1] 0]
return [_wwwEnsureOn $p 1]
}
"halfPageBack" {
getWinInfo a
set lines $a(linesdisp)
set top $a(currline)
set q [rowColToPos [expr $top - ${lines}/2] 0]
goto [rowColToPos [expr $top - ${lines}/2] 0]
return [_wwwEnsureOn $p 1]
}
}
}
}
}
##
# -------------------------------------------------------------------------
#
# "_wwwEnsureOn" --
#
# Make sure pos 'p' lies in the visible window area. If it does not,
# goto the closest position 'q' which does. If 'force', then
# provided 'p' is on-window, we goto it. Return values indicate
# in which direction to look for the rest of the visible window.
# -------------------------------------------------------------------------
##
proc _wwwEnsureOn {p {force 0}} {
getWinInfo a
set lines $a(linesdisp)
set top $a(currline)
set q [rowColToPos $top 0]
if {[pos::compare $q > $p]} {
goto $q
return 1
}
set q [pos::math [rowColToPos [expr $top + $lines] 0] - 1]
if {[pos::compare $q < $p]} {
goto $q
return 0
}
if {$force} {
goto $p
return 0
} else {
return ""
}
}
proc wwwMenuProc {menu item} {
if {$menu == "gotoPage"} {
# goto a history item
global _wwwHistory _wwwHpos
set pos [minPos]
foreach i $_wwwHistory {
if {[lindex $i 1] == $item} {
break
}
incr pos
}
if {$pos >= [llength $_wwwHistory]} {
alertnote "Sorry, I couldn't find that page!"
}
set _wwwHpos $pos
eval _wwwParseFile [lindex $_wwwHistory $_wwwHpos]
_wwwHighlightLink [lindex [wwwGetCurrentLink] 1]
return
}
switch $item {
"switchToBrowser" {
global browserSig
app::launchFore $browserSig
}
"viewHtmlFile" {
wwwParseFile [getfile "View which file"]
}
"viewThisFile" {
global mode
if {$mode == "HTML"} {
wwwParseFile [win::Current]
} else {
message "File must be HTML to be viewed!."
beep
}
}
"viewSource" {
global mode
if {$mode == "WWW"} {
global _wwwHistory _wwwHpos
if {[catch {file::openQuietly [lindex [lindex $_wwwHistory $_wwwHpos] 0]}]} {
alertnote "Sorry, I couldn't find that page!"
}
}
}
"forgetHistory" {
global _wwwHistory _wwwHpos _wwwVisited
set _wwwHistory ""
set _wwwHpos -1
set _wwwVisited ""
Menu -m -n gotoPage -p wwwMenuProc {}
}
default {
eval www[string toupper [string index $item 0]][string range $item 1 end]
}
}
}
proc wwwParseFile {{f ""} {title ""}} {
if {$f == ""} { set f [getfile "View which file"] }
_wwwParseFile $f $title
global _wwwHistory _wwwHpos
if {[set i [lsearch -glob $_wwwHistory [list * [win::Current]]]] != -1} {
set _wwwHpos $i
} else {
set _wwwHistory [lrange $_wwwHistory 0 $_wwwHpos]
incr _wwwHpos
lappend _wwwHistory [list $f [win::Current]]
foreach f $_wwwHistory {
lappend g [lindex $f 1]
}
Menu -m -n gotoPage -p wwwMenuProc $g
}
_wwwHighlightLink [lindex [wwwGetCurrentLink] 1]
wwwVisited $f
}
proc _wwwParseFile {f {title ""}} {
if {$title != ""} {
global wwwWhere
if {[info exists wwwWhere($title)]} {
if {![catch {bringToFront $title}]} {
return
}
}
}
if {[catch {
set fin [open $f r]
set t [read $fin]
close $fin
}]} {
catch {close $fin}
beep
alertnote "Sorry, I couldn't find and/or read that file."
error ""
}
message "Rendering…"
wwwParseText $t $f
message ""
}
proc wwwParseText {t {f ""}} {
set title "no-title"
regexp -nocase {<TITLE>(.*)</TITLE>} $t dummy title
global wwwWhere
if {[info exists wwwWhere($title)]} {
if {![catch {bringToFront $title}]} {
return
} else {
wwwNewWindow $t $title
return
}
}
set "wwwWhere($title)" $f
wwwNewWindow $t $title
}
proc wwwNewWindow {t title} {
set title [new -n $title -m WWW]
# ignore dirty flag and undo off.
setWinInfo shell 1
regexp -nocase {<BODY[^>]*>(.*)</BODY>} $t dummy t
catch {_wwwParseIntoWindow $t}
regsub -all {[][]} $title {\\&} title
setWinInfo read-only 1
#setWinInfo dirty 0
goto [minPos]
}
set wwwHtmlToStyle(B) bold
set wwwHtmlToStyle(I) italic
set wwwHtmlToStyle(U) underline
set wwwHtmlToStyle(BIG) outline
set wwwHtmlToStyle(SMALL) condensed
set wwwHtmlToStyle(EM) italic
set wwwHtmlToStyle(STRONG) bold
proc _wwwRemoveCrap {tt} {
upvar $tt t
regsub -all {alt="([^"]*)"[^>]*>} $t {>\1} t
regsub -all {<img[^>]*>} $t "" t
while {[set p [string first "<!--" $t]] != -1} {
set p2 [string first "-->" $t]
set t "[string range $t 0 [expr $p -1]][string range $t [expr $p2 + 3] end]"
}
while {[set p [string first "<FORM" $t]] != -1} {
set p2 [string first "/FORM>" $t]
set t "[string range $t 0 [expr $p -1]][string range $t [expr $p2 + 6] end]"
}
}
proc _wwwParseIntoWindow {t} {
global _wwwIndentation _wwwIndent
set _wwwIndentation 0
set _wwwIndent ""
_wwwRemoveCrap t
_wwwParseHtml $t
}
proc _wwwParseHtml {t} {
global _wwwIndentation _wwwIndent
while {[regexp {^([^<]*(<[<>][^<]*)*)<([^<>][^>]*)> *(.*)$} $t dummy first dmy html t]} {
wrapInsertText $first
switch -regexp [string toupper $html] {
"^A\\s+HREF\\s*=.*" {
set html [string range $html [expr 1+ [string first "=" $html]] end]
if {[regexp -nocase {^([^<]*)</A>(.*)$} $t "" name t]} {
wwwMakeLinkWord $name $html
}
}
"^A\\s+NAME\\s*=.*" {
set html [string range $html [expr 1+ [string first "=" $html]] end]
set html [string trim $html " \""]
setNamedMark $html [getPos] [getPos] [getPos]
}
"^(B|I|U|BIG|SMALL|EM|STRONG)\$" {
if {[regexp -nocase "^(\[^<\]*)</$html>(.*)\$" $t "" name t]} {
global wwwHtmlToStyle
wwwMakeColourWord $name $wwwHtmlToStyle([string toupper $html]) 12
}
}
"^/TR" {
insertText "\r"
}
"^(UL|DL|OL|BLOCKQUOTE)" {
_wwwNewLineIfNecessary
incr _wwwIndentation 3
append _wwwIndent " "
if {[string toupper $html] == "OL"} {
global _wwwOLcount$_wwwIndentation
set _wwwOLcount$_wwwIndentation 1
}
}
"^HR" {
_wwwBreakIfNecessary
insertText " ---------------------------------------------------------------- \r"
}
"^TD" {
#insertText " "
}
"^APPLET" {
_wwwSplit t </APPLET> pre
if {![regexp -nocase {code *= *([^.]*)\.class} $html dummy class]} {
set class "applet"
}
wwwMakeLinkWord "Run java $class" "\"${class}.java\""
}
"^PRE" {
global _wwwPre
set _wwwPre 1
#_wwwSplit t </PRE> pre
#insertText $pre
}
"^/PRE" {
global _wwwPre
set _wwwPre 0
}
"^/(UL|DL|OL|BLOCKQUOTE)" {
_wwwNewLineIfNecessary
if {[string toupper $html] == "/OL"} {
global _wwwOLcount$_wwwIndentation
unset _wwwOLcount$_wwwIndentation
}
incr _wwwIndentation -3
set _wwwIndent [string range $_wwwIndent 3 end]
}
"^LI" {
_wwwNewLineIfNecessary
global _wwwOLcount$_wwwIndentation
if {[info exists _wwwOLcount$_wwwIndentation]} {
insertText "[string range ${_wwwIndent} 2 end][set _wwwOLcount$_wwwIndentation] "
incr _wwwOLcount$_wwwIndentation
} else {
insertText "[string range ${_wwwIndent} 2 end]• "
}
}
"^DT" {
_wwwNewLineIfNecessary
#_wwwSplit t <DD> pre
insertText "[string range ${_wwwIndent} 2 end]"
}
"^DD" {
insertText " "
}
"^P" {
_wwwBreakIfNecessary
set t [string trimleft $t]
}
"^BR( .*)?" {
if {[lindex [posToRowCol [getPos]] 1] != 0} {
insertText "\r"
}
set t [string trimleft $t]
}
"^H\[0-9\]" {
set html [lindex $html 0]
set num [string range $html 1 end]
_wwwBreakIfNecessary
if {[regexp -nocase "^(\[^<\]*)</$html>(.*)\$" $t dummy name t]} {
switch $num {
1 {
insertText "\r"
global header1Color
wwwMakeColourWord $name $header1Color 0 outline
}
2 {
global header2Color
wwwMakeColourWord $name $header2Color 0 bold
}
default {
global header3Color
wwwMakeColourWord $name $header3Color 0
}
}
}
insertText "\r\r"
}
"^COMMENT" {
_wwwSplit t </COMMENT> pre
}
"^EMBED\\s+" {
if {[regexp -nocase {src *= *"([^"]+)"} $html dummy embed]} {
set name "???"
regexp {[^/:]+$} $embed name
wwwMakeLinkWord "Embedded '$name'." $embed
}
}
"^/.*" {
}
default {
set html [lindex $html 0]
if {[regexp -nocase "^(\[^<\]*)</$html>(.*)\$" $t dummy name t]} {
wrapInsertText $name
}
}
}
}
wrapInsertText $t
}
proc _wwwBreakIfNecessary {} {
if {[lookAt [pos::math [getPos] - 1]] != "\r"} {
insertText "\r"
}
if {[lookAt [pos::math [getPos] - 2]] != "\r"} {
insertText "\r"
}
}
proc _wwwNewLineIfNecessary {} {
if {[lookAt [pos::math [getPos] - 1]] != "\r"} {insertText "\r"}
}
proc _wwwSplit {text at prefix} {
upvar $prefix a
upvar $text t
if {[set p [string first $at [string toupper $t]]] == -1} {
set a $t
set t ""
} else {
set a [string range $t 0 [expr $p -1]]
set t [string range $t [expr $p + [string length $at]] end]
}
}
proc wrapInsertText {text} {
global _wwwPre
if {!$_wwwPre} {
regsub -all "\[\t\r\n \]+" [string trim $text] " " text
}
regsub -all " " $text " " text
regsub -all "&" $text {\&} text
regsub -all "<" $text "<" text
regsub -all ">" $text ">" text
regsub -all """ $text {"} text
if {$_wwwPre} {
insertText $text
return
}
if {$text == ""} { return }
set r [posToRowCol [getPos]]
set x [lindex $r 1]
global _wwwIndentation _wwwIndent
if {$x > 74} {
insertText "\r$_wwwIndent"
set x 0
}
if {$x == 0} {
incr x $_wwwIndentation
} else {
if {[regexp {^\w} $text]} {
if {[regexp {\w} [lookAt [pos::math [getPos] - 1]]]} {
insertText " "
incr x
}
}
}
set fc [expr 75 - $x]
while {[string length $text] > $fc} {
set f [string last " " [string range $text 0 $fc]]
if {$f == -1} {
set f $fc
}
insertText "[string range $text 0 $f]\r$_wwwIndent"
set text [string range $text [incr f] end]
set fc [expr 75 - $_wwwIndentation]
}
insertText $text
}
proc wwwMakeColourWord {word ind ind2 {with ""}} {
wwwDoColour $ind $with
wrapInsertText $word
wwwDoColour $ind2 12
}
proc wwwDoColour {ind {with ""}} {
set p [getPos]
insertColorEscape $p $ind
if {$with != ""} {
insertColorEscape $p $with
}
}
proc wwwMakeColour {from to ind ind2} {
insertColorEscape $from $ind
insertColorEscape $to $ind2
}
proc wwwMakeLinkWord {word link} {
if {$word == ""} { return }
set p [getPos]
if {[regexp {\w} [lookAt [pos::math $p - 1]]]} {
insertText " "
set p [pos::math $p + 1]
}
set cmd "wwwLink [set link [string trim $link]]"
insertColorEscape $p [_wwwLinkColour $link]
insertColorEscape $p 15 $cmd
wrapInsertText $word
set p [getPos]
insertColorEscape $p 12
insertColorEscape $p 0
}
proc _wwwLinkColour {link} {
global linkColor visitedLinkColor _wwwVisited
if {[lsearch -exact $_wwwVisited [string trim $link {"}]] == -1} {
return $linkColor
} else {
return $visitedLinkColor
}
}
proc wwwMakeLink {from to link} {
set cmd "wwwLink [set link [string trim $link]]"
insertColorEscape $from [_wwwLinkColour $link]
insertColorEscape $from 15 $cmd
insertColorEscape $to 12
insertColorEscape $to 0
}
proc _wwwSynchroniseHistoryPos {} {
global _wwwHistory _wwwHpos
set w [win::Current]
regsub -all {[][]} $w {\\&} w
set _wwwHpos [lsearch -glob $_wwwHistory [list * $w]]
#set _wwwHistory [lrange $_wwwHistory 0 $_wwwHpos]
}
proc wwwVisited {to} {
global _wwwVisited
if {[lsearch -exact $_wwwVisited $to] == -1} {
lappend _wwwVisited $to
}
}
proc wwwLink {to} {
wwwVisited $to
_wwwSynchroniseHistoryPos
if {[set l [string first ":" $to]] == -1} {
# it's local
_wwwSplit to "\#" pre
if {[string length $pre]} {
global wwwWhere
switch [file extension $pre] {
".class" -
".java" {
set pref "java"
}
default {
set pref "file"
}
}
wwwLink "${pref}://[file dirname $wwwWhere([win::Current])]/$pre"
}
gotoMark $to
_wwwHighlightLink [lindex [wwwGetCurrentLink] 1]
return
}
set p [string trimleft [string range $to [expr $l +1] end] "/"]
set urlType [string range $to 0 [expr $l -1]]
global wwwUrlAction
if {[info exists wwwUrlAction($urlType)]} {
# do we handle this internally
global ${urlType}LinksInternal
global _wwwAlwaysInternal
if {[lsearch -exact $_wwwAlwaysInternal $urlType] != -1 \
|| ([info exists ${urlType}LinksInternal] \
&& [set ${urlType}LinksInternal]) } {
$wwwUrlAction($urlType) $p
return
}
}
# if we didn't return above
wwwExternalLink $to
}
proc _wwwMassagePath {pp} {
upvar $pp p
regsub -all "/" $p ":" p
regsub -all {[^:]+:\.\.:} $p "" p
}
proc fileWWWLink {p} {
_wwwMassagePath p
global ModeSuffixes
if {[case [file extension $p] $ModeSuffixes] == "HTML"} {
wwwParseFile $p
} else {
file::openQuietly $p
}
}
proc javaWWWLink {p} {
global runJavaAppletsDirectly
if {$runJavaAppletsDirectly} {
# can run applet directly
_wwwMassagePath p
alertnote "Sorry, I don't yet know how to run .class files directly."
javaRun "[file root ${p}].class"
} else {
# use html file
global javaviewerSig _wwwHistory _wwwHpos
set app [file tail [app::launchFore $javaviewerSig]]
sendOpenEvent -n $app [lindex [lindex $_wwwHistory $_wwwHpos] 0]
}
}
proc ftpWWWLink {p} {
url::parseFtp $p i
ftpBrowse $i(host) $i(path) $i(user) $i(pass) $i(file)
}
proc wwwExternalLink {to} {
global wwwSendRemoteLinks
if {$wwwSendRemoteLinks} {
icURL $to
} else {
alertnote "External link to $to, toggle this mode's flags to use a helper instead of this message."
}
}
proc wwwForward {} {
global _wwwHistory _wwwHpos
if {$_wwwHpos < [expr [llength $_wwwHistory] -1]} {
incr _wwwHpos
eval _wwwParseFile [lindex $_wwwHistory $_wwwHpos]
} else {
beep
message "Already at most recent document."
}
}
proc wwwReload {} {
global _wwwHistory _wwwHpos
killWindow
eval _wwwParseFile [lindex $_wwwHistory $_wwwHpos]
}
proc wwwBack {} {
global _wwwHistory _wwwHpos
if {$_wwwHpos > 0} {
incr _wwwHpos -1
eval _wwwParseFile [lindex $_wwwHistory $_wwwHpos]
} else {
beep
message "Already at first document."
}
}
proc wwwSelectLink {} {
set link [wwwGetCurrentLink]
set link [_wwwHighlightLink [lindex $link 0]]
set p [getPos]
set q [selEnd]
select $p $p
select $p $q
wwwLink $link
}
proc wwwEditLinkedDocument {} {
set to [_wwwHighlightLink [lindex [wwwGetCurrentLink] 0]]
if {[set l [string first ":" $to]] == -1} {
# it's local
_wwwSplit to "\#" pre
global wwwWhere
if {[string length $pre]} {
_wwwEditLinkedDoc "file://[file dirname $wwwWhere([win::Current])]/$pre"
} else {
_wwwEditLinkedDoc "file://$wwwWhere([win::Current])"
}
return
}
_wwwEditLinkedDoc $to
}
proc _wwwEditLinkedDoc {to} {
set l [string first ":" $to]
set p [string trimleft [string range $to [expr $l +1] end] "/"]
_wwwMassagePath p
if {[catch {file::openQuietly $p}]} {
alertnote "Sorry, I can't edit and/or find that document."
}
}
proc wwwModifyLink {} {
global mode
if {$mode != "WWW"} {
alertnote "Only useful in WWW browser mode."
return
}
global _wwwHistory _wwwHpos
set f [lindex [lindex $_wwwHistory $_wwwHpos] 0]
if {![file exists $f]} {
alertnote "Sorry, I couldn't find that file!"
}
set w [win::Current]
if {![catch {getWinInfo -w $f i}]} {
if {$i(dirty)} {
message "Saving original file."
bringToFront $f
save
bringToFront $w
}
}
set link [wwwGetCurrentLink]
_wwwHighlightLink [lindex $link 0]
set p [getPos]
set q [selEnd]
regexp "\{ $p 15 \{wwwLink \"(\[^\"\]*)\"\} \} \{ $q 12 \}" [getColors] dmy link
set link "\"$link\""
set to [getline "Enter new link location" $link]
if {$to == "" || $to == $link} {
return
}
if {![regexp {^"} $to]} { set to "\"$to" }
if {![regexp {"$} $to]} { append to {"} }
set link [quote::Regfind $link]
set to [quote::Regsub $to]
set cid [open $f "r"]
if {[regsub -all -- $link [read $cid] $to out]} {
set ocid [open $f "w+"]
puts -nonewline $ocid $out
close $ocid
message "Updated original."
}
close $cid
if {![catch {bringToFront $f}]} {
message "Updating window to agree with disk version."
revert
bringToFront $w
}
setWinInfo read-only 0
wwwMakeLink $p $q $to
setWinInfo read-only 1
}
proc wwwUp {} {
set link [wwwGetCurrentLink]
_wwwHighlightLink [expr [lindex $link 1] -1]
}
proc wwwDown {} {
set link [wwwGetCurrentLink]
_wwwHighlightLink [expr [lindex $link 0] +1]
}
proc _wwwHighlightLink {l} {
global _wwwLinks
if {[set len [llength $_wwwLinks]] == 0} {return}
if {$l < 0 || $l >= $len} {
set l [expr ($l + $len) % $len]
beep
}
set link [lindex $_wwwLinks $l]
eval select $link
set p [getPos]
set q [selEnd]
regexp "\{ $p 15 \{wwwLink \"(\[^\"\]*)\"\} \} \{ $q 12 \}" [getColors] dmy link
message "Links to '$link'"
return $link
}
proc wwwHighlightLink {l} {
global _wwwLinks
set _wwwLinks [_wwwGetLinks]
_wwwHighlightLink $l
}
proc wwwGetCurrentLink {} {
global _wwwLinks
set _wwwLinks [_wwwGetLinks]
set p [getPos]
set i 0
while 1 {
if {[set j [lindex [lindex $_wwwLinks $i] 0]] == ""} {
return [list [expr $i-2] [expr $i-1]]
}
if {$p <= $j} {
if {$p == $j} {
return [list $i $i]
} else {
return [list [expr $i-1] $i]
}
}
incr i
}
incr i -1
return [list $i $i]
}
proc wwwCopyLinkLocation {} {
alertnote "Unimplemented."
}
proc _wwwGetLinks {} {
regsub -all {\{wwwLink "[^"]*"\} } [getColors] "" g
# remove all non 12,15 items
regsub -all {\{ [0-9]+ ([0-9]|1[0134]) \} ?} $g "" g
# remove superimposed links (caused by editing)
regsub -all {(\{ [0-9]+ 15 \} )+(\{ [0-9]+ 15 \} ?)} $g {\2} g
# convert 15-12 list pairs into single items
regsub -all { ([0-9]+) 15 \} \{ ([0-9]+) 12 } $g {\1 \2} g
# remove random left-overs items
regsub -all {\{ [0-9]+ 12 \} ?} $g "" g
return $g
}